package com.oristand.printer.address.util;

import com.oristand.printer.address.model.PrinterConfiguration;
import com.zebra.sdk.comm.Connection;
import com.zebra.sdk.comm.ConnectionException;
import com.zebra.sdk.comm.DriverPrinterConnection;
import com.zebra.sdk.comm.TcpConnection;
import com.zebra.sdk.printer.PrinterStatus;
import com.zebra.sdk.printer.ZebraPrinter;
import com.zebra.sdk.printer.ZebraPrinterFactory;
import com.zebra.sdk.printer.discovery.DiscoveredPrinterDriver;
import javafx.application.Platform;
import javafx.collections.ObservableList;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author chenkailiang
 * @date 2020/11/16
 */
public class PrinterUtil {

    /**
     * 从数据库获取打印机配置
     *
     * @return 打印机配置
     */
    public static  PrinterConfiguration getPrinter(){
        PrinterConfiguration printerConfiguration = null;
        try {
            SqliteUtil sqliteUtil = new SqliteUtil(Constants.LOCAL_PRINTER_CONFIGURATION);
            String sql = "select connectionType,printerName,ipAddress,port from printerConfiguration limit 1";
            List<PrinterConfiguration> list = sqliteUtil.executeQuery(sql, CommonMethodUtil :: getPrinterConfigurationFromResultSet);
            if(list!=null && !list.isEmpty()){
                printerConfiguration = list.get(0);
            }
        } catch (Exception e) {
            CommonMethodUtil.tipAlert(Constants.DATABASE_ERROR,e);
        }
        return printerConfiguration;
    }

    /**
     * 获取与打印机的连接
     *
     * @return 连接对象
     * @throws ConnectionException 连接异常
     */
    public static Connection getConnection(ObservableList<DiscoveredPrinterDriver> list ) throws ConnectionException {
        //从数据库查询配置
        PrinterConfiguration printerConfiguration = getPrinter();
        if(printerConfiguration == null ){
            return null;
        }
        if(Constants.CONNECTION_TYPE_USB.equals(printerConfiguration.getConnectionType())) {
            for (DiscoveredPrinterDriver driver : list) {
                if (driver.printerName.equals(printerConfiguration.getPrinterName())) {
                    return new DriverPrinterConnection(driver.printerName);
                }
            }
        }else{
            return new TcpConnection(printerConfiguration.getIpAddress(),Integer.parseInt(printerConfiguration.getPort()));
        }
        return null;
    }



    /**
     * try with resource 关闭连接
     *
     * @param connection 打印机连接
     */
    public static void closeConnection(Connection connection){
        try {
            if(connection != null){
                connection.close();
            }
        } catch (ConnectionException e) {
            Platform.runLater(()->CommonMethodUtil.tipAlert(Constants.PRINTER_NOT_CONNECTED,e));
        }
    }

    /**
     * 打印机连接时获取打印机状态
     * @return true/false
     */
     static  boolean checkPrinterStatus(ObservableList<DiscoveredPrinterDriver> list ){
        PrinterStatus printerStatus = null;
        Connection connection = null;
        boolean result = true;
        try {
            connection = getConnection(list);
            if(connection == null){
                return false;
            }
            TimeUnit.MILLISECONDS.sleep(500L);
            connection.open();
            TimeUnit.MILLISECONDS.sleep(500L);
            ZebraPrinter printer = ZebraPrinterFactory.getInstance(connection);
            printerStatus = printer.getCurrentStatus();
        } catch (Exception e) {
            Platform.runLater(()->CommonMethodUtil.tipAlert(Constants.PRINTER_NOT_CONNECTED,e));
            result =  false;
        }finally {
            try {
                if(connection != null){
                    connection.close();
                }
            } catch (ConnectionException e) {
                Platform.runLater(()->CommonMethodUtil.tipAlert(Constants.PRINTER_NOT_CONNECTED,e));
                result = false;
            }

        }
        if(printerStatus == null){
            Platform.runLater(()->CommonMethodUtil.tipAlert(Constants.PRINTER_NOT_CONNECTED,null));
            result =  false;
        }
        return result;

    }
}
